package com.weiyu.bultrasound.core.service.Impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jcraft.jsch.SftpException;
import com.weiyu.bultrasound.common.util.HttpUtil;
import com.weiyu.bultrasound.common.util.JSONUtils;
import com.weiyu.bultrasound.common.util.MD5Util;
import com.weiyu.bultrasound.common.util.SFTPUtil;
import com.weiyu.bultrasound.core.model.entity.Applications;
import com.weiyu.bultrasound.core.model.entity.Files;
import com.weiyu.bultrasound.core.model.request.*;
import com.weiyu.bultrasound.core.model.response.CommonResponse;
import com.weiyu.bultrasound.core.model.response.FilesImportResponseBody;
import com.weiyu.bultrasound.core.model.vo.ApplicationsVO;
import com.weiyu.bultrasound.core.service.ApplicationsService;
import com.weiyu.bultrasound.core.service.FilesService;
import com.weiyu.bultrasound.core.service.FilesUploadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 *@description 
 *@author abner chow
 *@date 2019-08-20 10:45
 */
@Service
public class FilesUploadServiceImpl implements FilesUploadService {

    private static final Logger logger = LoggerFactory.getLogger(FilesUploadServiceImpl.class);

    @Autowired
    ApplicationsService applicationsService;

    @Autowired
    FilesService filesService;

    @Value("${ftpconfig.username}")
    private String username;

    @Value("${ftpconfig.password}")
    private String password;

    @Value("${ftpconfig.host}")
    private String host;

    @Value("${ftpconfig.port}")
    private int port;

    @Value("${ftpconfig.basepath}")
    private String basepath;

    @Value("${ftpconfig.directory}")
    private String directory;

    @Value("${ftpconfig.import.action}")
    private String action;


    /**
     * @description 同步申请单文件到Ftp服务器
     * @Param: [ApplicationsId]
     * @Return: Boolean
     * @Author: abner chow
     * @Date: 2019/8/20 10:46
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean synFilesToFtp(Long applicationsId) {
        //是否该申请单的所有文件全部写入成功标志
        Boolean flag = Boolean.TRUE;
        ApplicationsVO applicationsVO = applicationsService.getById(applicationsId);
        if (null != applicationsVO && StringUtils.hasText(applicationsVO.getApplyCode())) {
            //所有文件
            List<Files> all = filesService.getByApplicationsId(applicationsId);
            //已同步文件列表
            List<Files> synList = filesService.getSynchronizeList(applicationsId);
            if ((!CollectionUtils.isEmpty(all)) && (!CollectionUtils.isEmpty(synList)) && all.size() == synList.size()) {
                //判断是否已同步
                if (applicationsVO.getStatus().equals("4")) {
                    return Boolean.TRUE;
                } else {
                    //所有文件已同步到ftp服务器但是调用文件上传接口失败的情况，重新请求一下
                    try {
                        //调用移动5G的文件导入接口
                        CommonResponse commonResponse = fileImport(applicationsVO);
                        if (commonResponse.getHeader().getResultCode().equals("0")) {
                            //更新申请单状态
                            applicationsService.save(Applications.builder().id(applicationsId).status(4).modifyTime(new Date()).build());
                            return Boolean.TRUE;
                        }
                    } catch (IOException e) {
                        logger.error("请求移动5G的文件上传接口失败");
                        e.printStackTrace();
                    }
                }
            }
            //未同步列表
            List<Files> filesList = filesService.getUnSynchronizeList(applicationsId);
            String applyCode = applicationsVO.getApplyCode();
            String location = directory + "/" + applyCode;
            if (!CollectionUtils.isEmpty(filesList)) {
                SFTPUtil sftp = new SFTPUtil(username, password, host, port);
                sftp.login();
                //拉取申请单的文件列表
                List<Files> list = applicationsVO.getFilesList();
                for (Files files : filesList) {
                    try {
                        logger.info(files.toString());
                        String finalLocal = null;
                        if (StringUtils.hasText(files.getPath())) {
                            Boolean f = sftp.upload(basepath, location, files.getName(), HttpUtil.getStreamByUrl(files.getPath().replaceAll(" ", "%20")));
                            finalLocal = location + "/" + files.getName();
                            logger.info("完整的ftp路径为：" + finalLocal);
                            //上传成功则更新文件的ftp地址
                            if(f){
                                files.setFtpPath(finalLocal);
                                filesService.updateById(files);
                                logger.info("成功更新文件id:"+ files.getId() +" 的ftp地址为:" + finalLocal);
                                if (!CollectionUtils.isEmpty(list)) {
                                    for (Files files1 : list) {
                                        if (files1.getId().equals(files.getId())) {
                                            files1.setFtpPath(finalLocal);
                                        }
                                    }
                                }
                            }else {
                                flag = Boolean.FALSE;
                            }
                        } else {
                            flag = Boolean.FALSE;
                            logger.info("文件id为：" + files.getId() + " 的地址为空");
                        }
                    } catch (SftpException e) {
                        e.printStackTrace();
                        flag = Boolean.FALSE;
                        logger.error(e.toString());
                        e.printStackTrace();
                    }
                }
                applicationsVO.setFilesList(list);
                //关闭资源
                sftp.logout();
                //  判断所有未同步文件是否写入成功，请求移动5G的文件上传接口, 成功同时更新申请单状态
                if (flag) {
                    try {
                        //调用移动5G的文件导入接口
                        CommonResponse commonResponse = fileImport(applicationsVO);
                        if (commonResponse.getHeader().getResultCode().equals("0")) {
                            //更新申请单状态
                            applicationsService.save(Applications.builder().id(applicationsId).status(4).modifyTime(new Date()).build());
                        }
                    } catch (IOException e) {
                        logger.error("请求移动5G的文件上传接口失败");
                        e.printStackTrace();
                    }
                }
            }
        }
        return flag;
    }

    /**
     * @description 调用移动5G的文件上传接口
     * @Param: [applicationsVO]
     * @Return: com.weiyu.bultrasound.core.model.response.CommonResponse
     * @Author: abner chow
     * @Date: 2019/8/21 16:51
     */
    protected CommonResponse<FilesImportResponseBody> fileImport(ApplicationsVO applicationsVO) throws IOException {
        CommonResponse<FilesImportResponseBody> commonResponse = new CommonResponse();
        CommonRequest<FilesImportRequestBody> commonRequest = new CommonRequest<>();
        commonRequest.setAction("TMIMedCartFileImport");
        //请求头
        RequestHeader requestHeader = new RequestHeader();
        requestHeader.setRequestId(UUID.randomUUID().toString().replaceAll("-", ""));
        Long time = new Date().getTime();
        requestHeader.setTimeStamp(time);
        requestHeader.setAppCode("0");
        requestHeader.setAppSecretKey("0");
        requestHeader.setAccessToken(MD5Util.getMD5String("0" + time.toString()));
        commonRequest.setHeader(requestHeader);
        //请求体
        FilesImportRequestBody filesImportRequestBody = new FilesImportRequestBody();
        filesImportRequestBody.setBusCode(applicationsVO.getBusCode());
        filesImportRequestBody.setApplyCode(applicationsVO.getApplyCode());
        List<DiagnoseResult> resultList = new ArrayList();
        DiagnoseResult diagnoseResult = new DiagnoseResult();
        BeanUtils.copyProperties(applicationsVO, diagnoseResult);
        diagnoseResult.setCreateTime(applicationsVO.getBeginTime());
        List<Files> filesList = applicationsVO.getFilesList();
        if (!CollectionUtils.isEmpty(filesList)) {
            List<UltraFiles> list = new ArrayList<>();
            for (Files files : filesList) {
                if(files.getFtpPath()!= null){
                    list.add(UltraFiles.builder().fileName(files.getName()).filePath(files.getFtpPath()).fileTypeCode(files.getTypeCode()).build());
                }
            }
            diagnoseResult.setUltraFiles(list);
        }
        resultList.add(diagnoseResult);
        filesImportRequestBody.setDiagnoseResult(resultList);
        commonRequest.setBody(filesImportRequestBody);
        logger.info("请求实体json：" + JSONUtils.beanToJson(commonRequest));
        String responStr = HttpUtil.httpPostWithjson(action, JSONUtils.beanToJson(commonRequest));
        logger.info("请求移动5G的文件上传接口的回调结果：" + responStr);
        if (StringUtils.hasText(responStr)) {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            commonResponse = mapper.readValue(responStr, new TypeReference<CommonResponse<FilesImportResponseBody>>() {
            });
        }
        return commonResponse;
    }


}
